/*
*
* 版权所有 Copyleft(c) 2005
* 刘炯个人工作室 Sharp-Mark Personal Studio
*
* 允许自由使用，复制，修改，传播和贩卖此源程序及其文档，而不必支付任何费用。
* 以上的版权信息必须出现在每一份复制品中。同时这份版权信息和许可声明
* 也必须出现在支持文档中。刘炯个人工作室不对此软件适于那种具体
* 用途做出任何阐述。此代码只作为代码本身提供对其品质不做任何保证。
*
*/

#include "stdafx.h"
#include "Hanoi.h"

Tower::Tower()
{
}
void Tower::PushOnePlate(int value)			// 移入一个块
{
	Plates.push_back(value);
}

int Tower::PopOnePlate()						// 移出一个块
{
	// 取得要移出的块的值，也就是它的代号
	vector<int>::iterator p = Plates.end();
	int value = *(--p);
	Plates.pop_back();

	return value;
}

Hanoi::Hanoi(int level)
: _level(level), _step(0)
{
	// 给三个柱子初始化
	if(level > 0)
	{
		do {
			_towers[0].PushOnePlate(level--);
		}while(level > 0);
	}
	_towers[1].Plates.clear();
	_towers[2].Plates.clear();
}

void Hanoi::MovePlates(Tower& towersource, Tower& towertransfer, Tower& towerdestination, int level)
{
	// 递归...
	if(level > 1)
	{
		MovePlates(towersource, towerdestination, towertransfer, level - 1);
		MovePlates(towersource, towertransfer, towerdestination, 1);
		MovePlates(towertransfer, towersource, towerdestination, level - 1);
	}
	else
	{
		// 移动，从source tower到 destination tower...
		towerdestination.PushOnePlate( towersource.PopOnePlate() );
		++_step;

		// 画汉诺塔
		DrawHanoi();
	}
}

void Hanoi::Run()
{
	// 其他情况，不予以处理...
	if(_level < 1) return;

	// 初始调用，开始了
	MovePlates(_towers[0], _towers[1], _towers[2], _level);
}

void Hanoi::DrawHanoi()
{
	for (int i = 0; i < 3; i++)
	{
		cout << "Tower " << i << " has :";
		for (vector<int>::iterator p = _towers[i].Plates.begin(); p != _towers[i].Plates.end(); p++)
		{
			int x = *p;
			cout << x << " ";
		}
		cout << endl;
	}

	cout << "This is Step : " << _step << endl << endl;
}